package com.jbp.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jbp.dao.SendGiftRecordDao;
import com.jbp.model.Gift;
import com.jbp.model.SendGiftRecord;
import com.jbp.model.User;
import com.jbp.service.GiftService;
import com.jbp.service.SendGiftRecordService;
import com.jbp.service.UserLevelService;
import com.jbp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import com.jbp.utils.PageUtils;
import com.jbp.utils.Query;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 送礼记录(SendGiftRecord)表服务实现类
 * @author cc
 * @since 2020-06-26 16:23:34
 */
@Service
public class SendGiftRecordServiceImpl extends ServiceImpl<SendGiftRecordDao, SendGiftRecord> implements SendGiftRecordService {
    @Autowired
    private GiftService giftService;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserLevelService userLevelService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<SendGiftRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("to_user_id", params.get("userId"));
        queryWrapper.orderByDesc("id");
        IPage<SendGiftRecord> page = this.page(
                new Query<SendGiftRecord>().getPage(params),
                queryWrapper
        );
        page.getRecords().forEach(record -> {
            User fromUser = userService.getById(record.getFromUserId());
            record.setFromUserImg(fromUser.getImg());
            record.setFromUserName(fromUser.getName());
            record.setFromUserSex(fromUser.getSex());
            record.setFromUserLevel(fromUser.getLevel());
            record.setFromUserLevelOn(userLevelService.levelOn(fromUser.getId()));
        });
        return new PageUtils(page);
    }

    @Override
    public List<Gift> getGiftWall(Integer otherId) {
        List<SendGiftRecord> giftRecords = getBaseMapper().getGiftWall(otherId);
        List<Gift> gifts = giftRecords.stream().map((giftRecord) -> {
            Gift gift = giftService.getById(giftRecord.getGiftId());
            gift.setNum(giftRecord.getNum());
            return gift;
        }).sorted(Comparator.comparing(Gift::getCoin).reversed()).collect(Collectors.toList());
        return gifts;
    }

    @Override
    public List<SendGiftRecord> sendList(Map<String, Object> params) {
        List<SendGiftRecord> giftRecords = senderListFromCache(params);
        return giftRecords;
    }

    @Override
    public List<SendGiftRecord> senderListFromCache(Map<String, Object> params) {
        if (params.get("roomId")==null || "".equals(params.get("roomId"))) {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            String json = (String) valueOperations.get("sendList:" + params.get("type"));
            List<SendGiftRecord> cache = ( List<SendGiftRecord>) JSON.parse(json);
            return cache!=null ? cache : new ArrayList<>();
        } else {
            List<SendGiftRecord> giftRecords = baseMapper.reciverList(params);
            giftRecords.forEach(list->{
                formatRecord(list, list.getFromUserId());
                Integer roomId = Integer.parseInt(params.get("roomId").toString());
                list.setRoomId(roomId);
            });
            return giftRecords;
        }
    }

    @Override
    public void cacheSenderList() {
        Map<String, Object> params = new HashMap<>();
        params.put("roomId", null);

        params.put("type", "day");
        List<SendGiftRecord> heartListDay = baseMapper.reciverList(params);
        heartListDay.forEach(list->formatRecord(list, list.getFromUserId()));

        params.put("type", "week");
        List<SendGiftRecord> heartListWeek = baseMapper.reciverList(params);
        heartListWeek.forEach(list->formatRecord(list, list.getFromUserId()));

        params.put("type", "month");
        List<SendGiftRecord> heartListMonth = baseMapper.reciverList(params);
        heartListMonth.forEach(list->formatRecord(list, list.getFromUserId()));

        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("sendList:day", JSON.toJSONString(heartListDay), 15, TimeUnit.MINUTES);
        valueOperations.set("sendList:week", JSON.toJSONString(heartListWeek), 15, TimeUnit.MINUTES);
        valueOperations.set("sendList:month", JSON.toJSONString(heartListMonth), 15, TimeUnit.MINUTES);
    }

    @Override
    public List<SendGiftRecord> heartList(Map<String, Object> params) {
        List<SendGiftRecord> giftRecords = heartListFromCache(params);
        return giftRecords;
    }

    @Override
    public List<SendGiftRecord> heartListFromCache(Map<String, Object> params) {
        if (params.get("roomId")==null || "".equals(params.get("roomId"))) {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            String json = (String) valueOperations.get("heartList:" + params.get("type"));
            List<SendGiftRecord> cache = ( List<SendGiftRecord>) JSON.parse(json);
            return cache!=null ? cache : new ArrayList<>();
        } else {
            List<SendGiftRecord> giftRecords = baseMapper.heartList(params);
            giftRecords.forEach(list->{
                formatRecord(list, list.getToUserId());
                Integer roomId = Integer.parseInt(params.get("roomId").toString());
                list.setRoomId(roomId);
            });
            return giftRecords;
        }
    }

    @Override
    public void cacheHeartList() {
        Map<String, Object> params = new HashMap<>();
        params.put("roomId", null);

        params.put("type", "day");
        List<SendGiftRecord> heartListDay = baseMapper.heartList(params);
        heartListDay.forEach(list->formatRecord(list, list.getToUserId()));

        params.put("type", "week");
        List<SendGiftRecord> heartListWeek = baseMapper.heartList(params);
        heartListWeek.forEach(list->formatRecord(list, list.getToUserId()));

        params.put("type", "month");
        List<SendGiftRecord> heartListMonth = baseMapper.heartList(params);
        heartListMonth.forEach(list->formatRecord(list, list.getToUserId()));

        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("heartList:day", JSON.toJSONString(heartListDay), 15, TimeUnit.MINUTES);
        valueOperations.set("heartList:week", JSON.toJSONString(heartListWeek), 15, TimeUnit.MINUTES);
        valueOperations.set("heartList:month", JSON.toJSONString(heartListMonth), 15, TimeUnit.MINUTES);
    }

    private void formatRecord(SendGiftRecord record, Integer userId) {
        if (userId!=null) {
            User user = userService.getById(userId);
            if (user!=null) {
                record.setFromUserName(user.getName());
                record.setFromUserSex(user.getSex());
                record.setFromUserImg(user.getImg());
                record.setFromUserId(user.getId());
                record.setFromUserLevel(user.getLevel());
                record.setFromUserLevelOn(userLevelService.levelOn(user.getId()));
            }
        }
    }
}